﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using System.Web;
using System.Collections.Specialized;

namespace MAF.Common
{
    /// <summary>
    /// 
    /// </summary>
    /// <typeparam name="T"></typeparam>
    [Obsolete("此类将由非泛型的同名类型取代")]
    public class Query<T> : IEnumerable<Criterion<T>>
    {
        /// <summary>
        /// Criterion 集合
        /// </summary>
        private List<Criterion<T>> _Items = new List<Criterion<T>>();

        /// <summary>
        /// 索引器
        /// </summary>
        /// <param name="i"></param>
        /// <returns></returns>
        public Criterion<T> this[int i]
        {
            get
            {
                return _Items[i];
            }
            set
            {
                _Items[i] = value;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        public int Count
        {
            get { return _Items.Count; }
        }

        /// <summary>
        /// 增加过滤规则
        /// </summary>
        /// <param name="key"></param>
        /// <param name="op"></param>
        /// <param name="value"></param>
        public void AddCriterion(string key, Op op, object value)
        {
            _Items.Add(new Criterion<T>(key, op, value));
        }

        /// <summary>
        /// 增加过滤规则：通过自动解析查询字符串为查询条件
        /// </summary>
        public void AddCriterionsByQueryString(string querystring)
        {
            NameValueCollection nvc = HttpUtility.ParseQueryString(querystring);
            foreach (string s in nvc)
            {
                _Items.Add(new Criterion<T>(s, Op.Equals, nvc[s]));
            }
        }

        #region 实现迭代器

        /// <summary>
        /// 泛型迭代器
        /// </summary>
        /// <returns></returns>
        public IEnumerator<Criterion<T>> GetEnumerator()
        {
            int count = _Items.Count;
            for (int i = 0; i < count; ++i)
            {
                yield return _Items[i];
            }
        }

        /// <summary>
        /// 非泛型迭代器
        /// </summary>
        /// <returns></returns>
        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }

        #endregion
    }

    /// <summary>
    /// 不要手工创建此类的对象，它有Query&lt;T&lt;创建
    /// </summary>
    /// <typeparam name="T"></typeparam>
    [Obsolete("此类将由非泛型的同名类型取代")]
    public class Criterion<T>
    {
        /// <summary>
        /// 键
        /// </summary>
        public string Key = string.Empty;

        /// <summary>
        /// 操作
        /// </summary>
        public Op Op = Op.Equals;

        /// <summary>
        /// 值
        /// </summary>
        public object Value = new Object();

        /// <summary>
        /// 构造方法
        /// </summary>
        /// <param name="key"></param>
        /// <param name="op"></param>
        /// <param name="value"></param>
        public Criterion(string key, Op op, object value)
        {
            Key = key;
            Op = op;
            Value = value;
        }

        /// <summary>
        /// 查询条件是否匹配参数指定的对象
        /// </summary>
        /// <param name="target"></param>
        /// <returns></returns>
        public bool IsMath(T target)
        {
            // 获取类型
            Type targetType = typeof(T);

            // 创建对象
            //object objInstance = Activator.CreateInstance(objType);
            var arry = Key.Split(". ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);

            // 判断属性是否存在
            if (!IsExistsProperty(targetType, Key))
                return false;

            // 获取属性值
            // TODO: 这里可以考虑改为ReflectHelper.GetMemberValue
            object val = targetType.InvokeMember(arry[0], BindingFlags.GetField | BindingFlags.GetProperty, null, target, null);

            // 处理null的情景
            if (null == val)
                return val == Value;

            // 处理其他情景
            if (1 < arry.Length)
            {
                for (int i = 1, len = arry.Length; i < len; ++i)
                {
                    Type tempType = val.GetType();
                    val = tempType.InvokeMember(arry[i], BindingFlags.GetField | BindingFlags.GetProperty, null, val, null);
                }
            }

            if (val is IComparable) // 判断是否具有IComparable接口，以确定是否存在CompareTo()方法
            {
                var r = (val as IComparable).CompareTo(Value);
                switch (this.Op)
                {
                    case MAF.Common.Op.Equals:
                        return 0 == r;
                    case MAF.Common.Op.GreaterThan:
                        return 0 < r;
                    case MAF.Common.Op.LessThan:
                        return 0 > r;
                }
            }
            else if (val is string && MAF.Common.Op.Like == this.Op)
            {
                return -1 < (val as string).IndexOf(Value as string);
            }

            return false;
        }

        /// <summary>
        /// 生成Sql where 字句
        /// </summary>
        /// <returns></returns>
        public string GenSqlWhere() { return string.Empty; }

        /// <summary>
        /// 是否存在某属性（包括字段）
        /// </summary>
        /// <param name="type"></param>
        /// <param name="name"></param>
        /// <returns></returns>
        private bool IsExistsProperty(Type type, string name)
        {
            // 先搜索属性
            PropertyInfo prop = type.GetProperty(name);
            if (null != prop)
                return true;

            FieldInfo field = type.GetField(name);
            if (null != field)
                return true;

            return false;
        }
    }

    /// <summary>
    /// 操作枚举
    /// </summary>
    [Obsolete("此枚举将由Compare枚举取代")]
    public enum Op
    {
        Equals,
        GreaterThan,
        LessThan,
        Like
    }
}
